package com.demo.springmvc底层演示.demo4;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.HttpHeadersReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler;

// 返回值处理
public class Test {
	
	public static void main(String[] args) throws Exception {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
		Method method = Controller.class.getMethod("test1");
		Controller controller = new Controller();
		Object returnValue = method.invoke(controller);
		
		ModelAndViewContainer container = new ModelAndViewContainer();
		MockHttpServletResponse response = new MockHttpServletResponse();
		ServletWebRequest webRequest = new ServletWebRequest(new MockHttpServletRequest(), response);
		HandlerMethod methodHandle= new HandlerMethod(controller, method);
		HandlerMethodReturnValueHandlerComposite composite = getReturnValueHandler();
		if(composite.supportsReturnType(methodHandle.getReturnType())) {
			composite.handleReturnValue(returnValue, methodHandle.getReturnType(), container, webRequest);
			System.out.println(container.getModel());
			System.out.println(container.getViewName());
		}
		
		method = Controller.class.getMethod("test5");
		returnValue = method.invoke(controller);
		
		methodHandle= new HandlerMethod(controller, method);
		if(composite.supportsReturnType(methodHandle.getReturnType())) {
			composite.handleReturnValue(returnValue, methodHandle.getReturnType(), container, webRequest);
			System.out.println(new String(response.getContentAsByteArray(), "utf-8"));
		}
	}
	
	/**返回值处理器
	 * @return
	 */
	private static HandlerMethodReturnValueHandlerComposite getReturnValueHandler() {
		HandlerMethodReturnValueHandlerComposite composite = new HandlerMethodReturnValueHandlerComposite();
		composite.addHandler(new ModelAndViewMethodReturnValueHandler());
		composite.addHandler(new ViewNameMethodReturnValueHandler());
		composite.addHandler(new ServletModelAttributeMethodProcessor(false));
		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>() {{
			add(new MappingJackson2HttpMessageConverter());
		}};
		composite.addHandler(new HttpEntityMethodProcessor(converters));
		composite.addHandler(new HttpHeadersReturnValueHandler());
		composite.addHandler(new RequestResponseBodyMethodProcessor(converters));
		composite.addHandler(new ServletModelAttributeMethodProcessor(true));
		return composite;
	}

}
